<?xml version="1.0" encoding="UTF-8"?>
<!--
    Document   : xdbforms.xsl
    Created on : 13 luglio 2009, 14.23
    Authors     : Gianfranco Murador, Matteo Ferri, Cristian Castiglia
    Copyight (C) 2009 MCG08 Group
    Licence : LGPL
    This code is
    Description:
        Definisce un document xsl per la trasformazione di un modello dati
        in documento xforms. Usare xsl per la trasformazione da una maggiore
        flessibilità al progetto nel cambiamento dei controlli xforms.
-->

<xsl:stylesheet version="2.0" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events">
    <xsl:output method="xhtml" version="1.0" encoding="UTF-8" indent="yes"/>
	<!-- Rappresentano una lista con i nomi dei tag, ossia i nomi delle colonne-->
    <xsl:param name="data-elements"/>
	<!-- rapprenta una lista con tutti i tipi delle colonne-->
    <xsl:param name="data-types"/>
	<!-- definisce l'url dello schema associato al modello -->
    <xsl:param name="schema_url"/>
	<!-- definisce il metodo di submission usato per la form -->
    <xsl:param name="submission_method"/>
	<!-- definisce l'url dove inoltrare i dati inseriti -->
    <xsl:param name="submission_url"/>
	<!-- Messaggio inserito sul button per la submit-->
    <xsl:param name="submission_msg"/>
	<!-- stile del documento -->
    <xsl:param name="style">xdbforms.css</xsl:param>
	<!-- titolo della pagina -->
    <xsl:param name="title"/>
	<!-- id del modello, rappresenta il nome della tabella del db-->
    <xsl:param name="model_id"/>
    <xsl:template match="/" name="main">
        <html>
            <head>
                <link rel="stylesheet" href="{$style}" type="text/css"/>
                <title>
                    <xsl:value-of select="$title"/>
                </title>
                <xf:model id="{$model_id}">
                    <xf:instance schema="{$schema_url}">
                        <xsl:call-template name="insert_model"/>
                    </xf:instance>
                    <xf:submission method="{$submission_method}" action="{$submission_url}">
                        <xf:action ev:event="xforms-submit-error">
                        </xf:action>
                    </xf:submission>
                </xf:model>
            </head>
            <body>
                <xsl:call-template name="build-xform-control">
                    <xsl:with-param name="elements" select="$data-elements"/>
                    <xsl:with-param name="types" select="$data-types"/>
                </xsl:call-template>
                <xf:submit model="{$model_id}">
                    <xf:label>
                        <xsl:value-of select="$submission_msg"/>
                    </xf:label>
                </xf:submit>
            </body>
        </html>
    </xsl:template>
	<!-- end main template -->
    <xsl:template name="build-xform-control">
		<!-- Se i dati sono stati passati-->
        <xsl:param name="elements"/>
        <xsl:param name="types"/>
        <xsl:if test="$types !='' and $elements !=''">
            <xsl:choose>
                <xsl:when test="contains($elements,' ') and contains($types, ' ')">
                    
                    <xsl:variable name="elem" select="substring-before($elements, ' ')"/>


                    <xsl:variable name="isAutoIncrElem" select="//data/substring-before($elements, ' ')/@isAutoincrement"/> 
                    <xsl:if test="$isAutoIncrElem">
                   
                        <xsl:call-template name="build-xform-control">
                            <xsl:with-param name="elements" select="substring-after($elements,' ')"/>
                            <xsl:with-param name="types" select="substring-after($types,' ')"/>
                        </xsl:call-template>
                    </xsl:if>

					<!-- se liste contengono almeno due elementi -->
					<!-- Sono di fronte ad una foreing key-->
                    <xsl:if test="contains(substring-before($types,' '),'_FK_')">
						<!-- uso un select1 per le chiavi esterne -->
                        <xsl:call-template name="select1-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                        <xsl:call-template name="build-xform-control">
                            <xsl:with-param name="elements" select="substring-after($elements,' ')"/>
                            <xsl:with-param name="types" select="substring-after($types,' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- se il tipo è un INTEGER -->
                    <xsl:if test="starts-with(substring-before($types,' '),'INTEGER') or
					                  starts-with(substring-before($types,' '),'INT') or
					                  starts-with(substring-before($types,' '),'BIGINT') or
					                  starts-with(substring-before($types,' '),'TINYINT') or
					                  starts-with(substring-before($types,' '),'MEDIUMINT')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se il tipo è un ENUM -->
                    <xsl:if test="starts-with(substring-before($types,' '),'ENUM')">
                        <xsl:call-template name="select1-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se il tipo è un SET-->
                    <xsl:if test="starts-with(substring-before($types, ' '), 'SET')">
                        <xsl:call-template name="select-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo CHAR, VARCHAR  .. -->
                    <xsl:if test="starts-with(substring-before($types, ' '),'CHAR') or
					                  starts-with(substring-before($types,' '),'VARCHAR')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo TEXT e suoi derivati -->
                    <xsl:if test="starts-with(substring-before($types,' '), 'TEXT') or
									   starts-with(substring-before($types,' '), 'MEDIUMTEXT') or
									   starts-with(substring-before($types,' '), 'LONGTEXT')">
                        <xsl:call-template name="textarea-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo BLOB e suoi derivati -->
                    <xsl:if test="starts-with(substring-before($types,' '), 'BLOB') or
						              starts-with(substring-before($types,' '), 'MEDIUMBLOB') or
						              starts-with(substring-before($types,' '), 'LONGBLOB') or
						              starts-with(substring-before($types,' '), 'BINARY')">
                        <xsl:call-template name="upload-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- tipo date -->
                    <xsl:if test="starts-with(substring-before($types,' '),'DATE')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>

					<!-- tipi derivati da data -->
                    <xsl:if test="starts-with(substring-before($types,' '), 'TIME') or
						              starts-with(substring-before($types,' '), 'DATETIME') or
						              starts-with(substring-before($types,' '), 'YEAR') or
						              starts-with(substring-before($types,' '), 'TIMESTAMP')">
                        <xsl:call-template name="range-control">
                            <xsl:with-param name="element" select="substring-before($elements, ' ')"/>
                            <xsl:with-param name="type" select="substring-before($types, ' ')"/>
                        </xsl:call-template>
                    </xsl:if>
                    <xsl:call-template name="build-xform-control">
                        <xsl:with-param name="elements" select="substring-after($elements,' ')"/>
                        <xsl:with-param name="types" select="substring-after($types,' ')"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
					<!-- FINE RICORSIONE SULL'ULTIMO ELEMENTO
						 se la lista contiene solo un elemento, ripeto i casi omettendo le operazioni di estrazione delle sottostringhe -->


                    <xsl:variable name="isAutoIncrElem" select="//data/$elements/@isAutoincrement"/>
                    <xsl:if test="$isAutoIncrElem">
                    <!-- Se e' un campo con etichetta autoincrement,
                        allora non occorre inserire alcun valore -->
                        <xsl:call-template name="build-xform-control">
                            <xsl:with-param name="elements" select="''"/>
                            <xsl:with-param name="types" select="''"/>
                        </xsl:call-template>
                    </xsl:if>

                    <xsl:if test="contains($types,'_FK_')">
						<!-- uso un select1 per le chiavi esterne -->
                        <xsl:call-template name="select1-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>

                    <xsl:if test="starts-with($types,'INT') or
					                  starts-with($types,'BIGINT') or
					                  starts-with($types,'TINYINT') or
					                  starts-with($types,'MEDIUMINT')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se il tipo è un ENUM -->
                    <xsl:if test="starts-with($types,'ENUM')">
                        <xsl:call-template name="select1-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>

					<!-- Se il tipo è un SET-->
                    <xsl:if test="starts-with($types, 'SET')">
                        <xsl:call-template name="select-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo CHAR, VARCHAR  .. -->
                    <xsl:if test="starts-with($types,'CHAR') or
					                  starts-with($types,'VARCHAR')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo TEXT e suoi derivati -->
                    <xsl:if test="starts-with($types, 'TEXT') or
									   starts-with($types, 'MEDIUMTEXT') or
									   starts-with($types, 'LONGTEXT')">
                        <xsl:call-template name="textarea-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>
					<!-- Se è di tipo BLOB e suoi derivati -->
                    <xsl:if test="starts-with($types, 'BLOB') or
						              starts-with($types, 'MEDIUMBLOB') or
						              starts-with($types, 'LONGBLOB') or
						              starts-with($types,'BINARY')">
                        <xsl:call-template name="upload-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>

						<!-- tipo date -->
                    <xsl:if test="starts-with($types,'DATE')">
                        <xsl:call-template name="input-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>

					<!-- tipi derivati da date -->

                    <xsl:if test="starts-with($types, 'TIME') or
						              starts-with($types, 'DATETIME') or
						              starts-with($types,'YEAR') or
						              starts-with($types, 'TIMESTAMP')">
                        <xsl:call-template name="range-control">
                            <xsl:with-param name="element" select="$elements"/>
                            <xsl:with-param name="type" select="$types"/>
                        </xsl:call-template>
                    </xsl:if>

                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>
    </xsl:template>
    <xsl:template name="insert_model">
        <xsl:copy-of select=".">
        </xsl:copy-of>
    </xsl:template>
	<!-- creo ogni template per ogni controllo xform -->
	<!-- controllo input text-->
    <xsl:template name="input-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:input ref="{$element}" incremental="true">
            <xf:label>
                <xsl:value-of select="$element"/>
            </xf:label>
        </xf:input>
    </xsl:template>
	<!-- controllo select1 -->
    <xsl:template name="select1-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:select1 selection="open" incremental="false" appearance="full" ref=".">
            <xf:label>
                <xsl:value-of select="$element"/>
            </xf:label>
            <xf:itemset nodeset="//admissible-values[@column=$element]/*">
                <xf:label>
                    <xf:output ref="."/>
                </xf:label>
                <xf:value>
                    <xf:value ref="."/>
                </xf:value>
            </xf:itemset>
        </xf:select1>
    </xsl:template>
	<!-- controllo select -->
    <xsl:template name="select-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:select selection="open" incremental="true" appearance="full" ref=".">
            <xf:label>
                <xsl:value-of select="$element"/>
            </xf:label>
            <xf:itemset nodeset="//admissible-values[@column=$element]/*">
                <xf:label>
                    <xf:output ref="."/>
                </xf:label>
                <xf:value>
                    <xf:value ref="."/>
                </xf:value>
            </xf:itemset>
        </xf:select>
    </xsl:template>
	<!-- controllo textarea -->
    <xsl:template name="textarea-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:textarea ref="{$element}">
            <xf:label>
                <xsl:value-of select="$element"/>
            </xf:label>
        </xf:textarea>
    </xsl:template>
	<!-- controllo upload -->
    <xsl:template name="upload-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:upload ref="{$element}">
            <xf:label>
                <xsl:value-of select="$element"/>
            </xf:label>
        </xf:upload>
    </xsl:template>
	<!-- range-control -->
    <xsl:template name="range-control">
        <xsl:param name="element"/>
        <xsl:param name="type"/>
        <xf:range ref="{$element}">
        </xf:range>
    </xsl:template>
</xsl:stylesheet>
